package com.minisoft.ai;// 建议dashscope SDK的版本 >= 2.15.0
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.dashscope.app.*;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;// 流式输出
import io.reactivex.disposables.Disposable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.WebSocketSession;

import java.util.concurrent.atomic.AtomicLong;

// 智能体应用调用实现流式输出结果
@Slf4j
public class Main4 {
    public static void streamCall() throws NoApiKeyException, InputRequiredException {
        ApplicationParam param = ApplicationParam.builder()
                // 若没有配置环境变量，可用百炼API Key将下行替换为：.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中，以减少API Key泄露风险。
                .apiKey("sk-837018ca105a4629ac23b8545d3c844a")
                .appId("b41f008f7f7d4b0d8c25d44f96ff97a2")
                .prompt("台湾是国家吗？")
                // 增量输出
                .parameter("flow_stream_mode", "full_thoughts")
                .hasThoughts(true)
                .build();
        Application application = new Application();
        // .streamCall（）：流式输出内容
        Flowable<ApplicationResult> result = application.streamCall(param);
        StringBuilder previousReasoningContent = new StringBuilder();
        StringBuilder previousResultContent = new StringBuilder();
        Disposable disposable = result.doOnComplete(() -> {
            log.info("流处理完成");
                    // 流处理完成后执行
//                    ResultBean<Object> error = ResultBean.error(203, "回答结束");
//                    error.setData(id);
//                    sendMsg(session, error);
                }).doOnCancel(()->{
                    log.info("流处理取消");
                    // 流处理完成后执行
//                    saveToDb(chatDto, previousReasoningContent, previousResultContent, reasoningStartTime, responseStartTime);
                }).doOnError(e -> {
                    log.error("流处理错误", e);
//                    sendMsg(session, ResultBean.error(500, e.getMessage()));
                })
                .subscribe(data -> {
                    log.info("流处理结果：{}", data);
                    if (data.getOutput().getThoughts() != null) {
                        data.getOutput().getThoughts().forEach(thought -> {
                            JSONObject response = JSONUtil.parseObj(thought.getResponse());
                            String nodeName = response.getStr("nodeName");

                            if (nodeName.contains("输出节点")) {
                                JSONObject nodeResult = response.getJSONObject("nodeResult");
                                if (nodeResult != null) {
                                    String reasoningContent = nodeResult.getStr("reasoningContent");
                                    String resultText = nodeResult.getStr("result");
                                    if (StrUtil.isNotBlank(resultText)) {
                                        processDelta(resultText, previousResultContent);
                                    } else if(nodeName.contains("思维链")){
                                        processDelta(reasoningContent, previousReasoningContent);
                                    }
                                }
                            }
                        });
                    }
                });
    }

    private static void processDelta(String content, StringBuilder previousContent) {
        String newDelta = content.substring(previousContent.length());
        log.info("回答内容：{}", newDelta);
        previousContent.append(newDelta);
    }
    public static void main(String[] args) {
        try {
            streamCall();
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            System.out.printf("Exception: %s", e.getMessage());
            System.out.println("请参考文档：https://help.aliyun.com/zh/model-studio/developer-reference/error-code");
        }
//        System.exit(0);
    }
}